﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace WebAPI.Utils;

//System.Type 类－－通过这个类可以访问任何给定数据类型的信息。
//System.Reflection.Assembly类－－它可以用于访问给定程序集的信息，或者把这个程序集加载到程序中。
public class ReflectionHelper
{
    #region 创建对象实例

    /// <summary>
    /// 创建对象实例
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <param name="assemblyName">程序集名称</param>
    /// <param name="nameSpace">命名空间</param>
    /// <param name="className">类名</param>
    /// <returns></returns>
    public static T CreateInstance<T>(string nameSpace, string className, string assemblyName)
    {
        try
        {
            //命名空间.类名,程序集
            var path = nameSpace + "." + className + "," + assemblyName;
            //加载类型
            var type = Type.GetType(path);
            //根据类型创建实例
            var obj = Activator.CreateInstance(type, true);
            //类型转换并返回
            return (T)obj;
        }
        catch
        {
            //发生异常时，返回类型的默认值。
            return default(T);
        }
    }

    #endregion

    #region 调用方法实例

    /// <summary>
    /// 调用方法实例
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <param name="assemblyName">程序集名称</param>
    /// <param name="nameSpace">命名空间</param>
    /// <param name="className">类名</param>
    /// <returns></returns>
    public static T GetInvokeMethod<T>(string assemblyName, string nameSpace, string className, string methodName, object[] paras)
    {
        try
        {
            //命名空间.类名,程序集
            var path = nameSpace + "." + className + "," + assemblyName;
            //加载类型
            var type = Type.GetType(path);
            //根据类型创建实例
            var obj = Activator.CreateInstance(type, true);
            //加载方法参数类型及方法
            MethodInfo method = null;
            if (paras != null && paras.Length > 0)
            {
                //加载方法参数类型
                var paratypes = new Type[paras.Length];
                for (var i = 0; i < paras.Length; i++)
                {
                    paratypes[i] = paras[i].GetType();
                }
                //加载有参方法
                method = type.GetMethod(methodName, paratypes);
            }
            else
            {
                //加载无参方法
                method = type.GetMethod(methodName);
            }
            //类型转换并返回
            return (T)method.Invoke(obj, paras);
        }
        catch
        {
            //发生异常时，返回类型的默认值。
            return default(T);
        }
    }

    public static T InvokeMethod<T> (Type t, MethodInfo m)
    {
        var obj = Activator.CreateInstance(t);
        return (T) m.Invoke(obj, null);
    }

    #endregion

    // var nameProp = PropertyName((Foo i) => i.Name);  
    public static string? PropertyName<TEntity, TProp>(Expression<Func<TEntity, TProp>> expression)  
    {  
        var member = expression.Body as MemberExpression;  
        return member?.Member.Name;  
    }
}